home *** CD-ROM | disk | FTP | other *** search
-
- /*
- File: ArcLibrary.c
-
- Contains: graphics libraries - arc and wedge functions
-
- Written by: Mike Reed
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <3> 4/7/95 jtd changed 'fract' to 'Fract'
- <2> 1/9/95 JD changed 'boolean' to 'Boolean'
- <1> 1/9/95 JD First checked in.
- Previous History:
-
- Sean Parent - fixed bug (first pt off gxCurve)
- - added code to obey sweep direction (negative is counter-clockwise)
- */
-
- #include "GraphicsLibraries.h"
-
- /*
- * Same as the QD call, but takes fixed parameters. The wedge boolean is set to false for FrameArc
- * and to true for everything else.
- */
-
- #define kFracCos45over2 0x3B20D79E
- #define kMaxArcPoints 13
-
- typedef struct {
- long count;
- long ctrBits;
- gxPoint data[kMaxArcPoints]; /* only need up to 12 + 1 for center of wedge */
- } tmpArcPathType;
-
-
- /*
- * Used by NewArc and SetArc, it sets 'aPathPtr'
- * (a tmpArcPathType) to the appropriate
- * wedge gxShape.
- */
- static void SetArcData(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge, tmpArcPathType *aPathPtr)
- {
- register long *ptWalker;
-
- aPathPtr->count = 0;
- aPathPtr->ctrBits = 0;
- {
- register Fixed halfWidth = (r->right - r->left + 1) >> 1;
- register Fixed halfHeight = (r->top - r->bottom + 1) >> 1;
- register Fixed sweepAng = sweep;
- register Fixed midPointAng;
- register unsigned long ctrBitMask = 0x40000000U;
- register short i;
- Fixed cosineValue;
- Fixed incrementAng;
- Fixed halfIncrementAng;
-
- if (sweep < 0) incrementAng = ff(-45);
- else incrementAng = ff(45);
- halfIncrementAng = incrementAng >> 1;
-
- midPointAng = startAng + halfIncrementAng;
- /*
- * Always set the first gxPoint
- */
- ptWalker = &aPathPtr->data[0].x;
- *ptWalker++ = FractMultiply(FractSineCosine(startAng, &cosineValue), halfWidth);
- *ptWalker++ = FractMultiply(cosineValue, halfHeight);
-
- for (i = FixedToInt(sweepAng) / FixedToInt(incrementAng) - 1; i >= 0; i--) {
- *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng, &cosineValue), kFracCos45over2);
- *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, kFracCos45over2);
- aPathPtr->ctrBits |= ctrBitMask;
- midPointAng += incrementAng;
- ctrBitMask >>= 1;
- sweepAng -= incrementAng;
- }
- /*
- * Finish with a short parabola if not on a 45 degree multiple
- */
- if (sweepAng != 0)
- { Fract lamda;
-
- sweepAng >>= 1;
- FractSineCosine(sweepAng, &lamda);
- midPointAng -= halfIncrementAng; /* reset to end of 45 degree segments */
- /*
- * Begin the short piece if we added OFF points earlier
- */
- if (ptWalker - &aPathPtr->data[0].x > 2) {
- *ptWalker++ = FractMultiply(FractSineCosine(midPointAng, &cosineValue), halfWidth);
- *ptWalker++ = FractMultiply(cosineValue, halfHeight);
- ctrBitMask >>= 1;
- }
- *ptWalker++ = MultiplyDivide(halfWidth, FractSineCosine(midPointAng + sweepAng, &cosineValue), lamda);
- *ptWalker++ = MultiplyDivide(halfHeight, cosineValue, lamda);
- aPathPtr->ctrBits |= ctrBitMask;
- }
- /*
- * Finish with the final ON gxPoint
- */
- *ptWalker++ = FractMultiply(FractSineCosine(startAng + sweep, &cosineValue), halfWidth);
- *ptWalker++ = FractMultiply(cosineValue, halfHeight);
- }
- /*
- * Time to make the gxPath
- */
- if (wedge) {
- *ptWalker++ = 0;
- *ptWalker++ = 0;
- }
- { register Fixed centerX = (r->right + r->left + 1) >> 1;
- register Fixed centerY = (r->bottom + r->top + 1) >> 1;
- register short counter = (ptWalker - &aPathPtr->data[0].x) >> 1;
-
- aPathPtr->count = counter;
- for (counter -= 1; counter >= 0; counter--) {
- *--ptWalker += centerY;
- *--ptWalker += centerX;
- }
- }
- }
-
-
- gxShape NewArc(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
- {
- tmpArcPathType aPath;
- gxShape arcShape;
-
- NilParamReturnNil(r);
- if ((sweep >= ff(360)) || (sweep <= ff(-360)))
- return NewOval(r);
-
- SetArcData(r,startAng,sweep,wedge,&aPath);
- arcShape = NewPath((gxPath *) &aPath);
-
- GXSetShapeFill(arcShape, wedge ? gxSolidFill : gxFrameFill);
- return arcShape;
- }
-
- void SetArc(gxShape sh, const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
- {
- tmpArcPathType aPath;
-
- NilParamReturn(r);
-
- if ((sweep >= ff(360)) || (sweep <= ff(-360))) SetOval(sh,r);
- else {
- SetArcData(r,startAng,sweep,wedge,&aPath);
- SetPath(sh, 0, (gxPath *) &aPath);
- }
- }
-
-
- void DrawArc(const gxRectangle *r, Fixed startAng, Fixed sweep, Boolean wedge)
- {
- gxShape arcShape;
-
- NilParamReturn(r);
- arcShape = NewArc(r, startAng, sweep, wedge);
- GXDrawShape(arcShape);
- GXDisposeShape(arcShape);
- }
-